package com.xukang.xkdemospringbootes7.controller;

import com.alibaba.fastjson.JSON;
import com.xukang.xkdemospringbootes7.pojo.Group;
import com.xukang.xkdemospringbootes7.pojo.Student;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
import org.elasticsearch.action.bulk.BulkRequest;
import org.elasticsearch.action.bulk.BulkResponse;
import org.elasticsearch.action.delete.DeleteRequest;
import org.elasticsearch.action.delete.DeleteResponse;
import org.elasticsearch.action.get.GetRequest;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.support.master.AcknowledgedResponse;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.action.update.UpdateResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;

import org.elasticsearch.client.indices.CreateIndexRequest;
import org.elasticsearch.client.indices.CreateIndexResponse;
import org.elasticsearch.client.indices.GetIndexRequest;
import org.elasticsearch.common.text.Text;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.TermQueryBuilder;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;


import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/*
*  es 7.6.x 集成 boot 高级 API
*
* */
@Controller
public class DemoController {

    @Autowired
    @Qualifier("restHighLevelClient")
    RestHighLevelClient client;

    public static String INDEX_SCHOOL = "jimoshiyan";

    /*索引操作，相当于 sqlku 的database*/
    @RequestMapping(value="index",method= RequestMethod.GET)
    @ResponseBody
    public void index() throws IOException {
        // 检查索引是否存在
        GetIndexRequest getIndexRequest = new GetIndexRequest("xukang_class");
        boolean exis = client.indices().exists(getIndexRequest, RequestOptions.DEFAULT);
        if(!exis){
            // 创建索引
            CreateIndexRequest createIndexRequest = new CreateIndexRequest("xukang_class");
            // 执行创建
            CreateIndexResponse createIndexResponse = client.indices().create(createIndexRequest, RequestOptions.DEFAULT);
            System.out.println("添加成功标志："+createIndexResponse.isAcknowledged());
        }
        // 删除索引
        DeleteIndexRequest dreq = new DeleteIndexRequest("xukang_class");
        AcknowledgedResponse del = client.indices().delete(dreq,RequestOptions.DEFAULT);
        System.out.println("删除成功标志："+del.isAcknowledged());

    }

    /*文档操作*/
    @RequestMapping(value="doc",method= RequestMethod.GET)
    @ResponseBody
    public void doc() throws IOException {

        Student xukang = new Student(101,"徐康",26,"迪丽热巴");
        // 创建请求
        IndexRequest request = new IndexRequest(INDEX_SCHOOL);
        // 规则 put /jimoshiyan/_doc/1
        String id = "1";
        request.id(id);
        request.timeout(TimeValue.timeValueSeconds(1));
        request.timeout("1s");

        // 将学生数据 放入请求 ，json格式
        request.source(JSON.toJSONString(xukang), XContentType.JSON);

        // 客户端发送请求
        IndexResponse indexResponse = client.index(request,RequestOptions.DEFAULT);
        System.out.println(indexResponse.status()); // 第一次 是create ，以后是update
        System.out.println(indexResponse.toString());


        // 检查文档
        GetRequest getRequest = new GetRequest(INDEX_SCHOOL,id);
        boolean exists = client.exists(getRequest,RequestOptions.DEFAULT);
        System.out.println("检查文档是否存在"+exists);

        // 获取文档
        GetResponse getResponse = client.get(getRequest,RequestOptions.DEFAULT);
        System.out.println(getResponse.getIndex());
        System.out.println(getResponse.getField("name")); //null
        System.out.println(getResponse.getFields());  //{}
        System.out.println(getResponse.getVersion());
        System.out.println(getResponse.getSeqNo());
        System.out.println(getResponse.getSourceAsMap());
        System.out.println(getResponse.getSourceAsString());
        System.out.println(getResponse);

        // 更新文档
        UpdateRequest updateRequest = new UpdateRequest(INDEX_SCHOOL,id);
        updateRequest.timeout("1s");
        Student xiali = new Student(102,"夏丽",26,"xukang");
        updateRequest.doc(JSON.toJSONString(xiali), XContentType.JSON);
        UpdateResponse updateResponse = client.update(updateRequest,RequestOptions.DEFAULT);
        System.out.println(updateResponse.status());
        System.out.println(updateResponse.toString());
        System.out.println(updateResponse);

        // 删除文档
        DeleteRequest deleteRequest = new DeleteRequest(INDEX_SCHOOL,id);
        DeleteResponse deleteResponse = client.delete(deleteRequest,RequestOptions.DEFAULT);
        System.out.println(deleteResponse.status());
        System.out.println(deleteResponse.toString());
    }

    /*批量插入*/
    @RequestMapping(value="bulkInsert",method= RequestMethod.GET)
    @ResponseBody
    public void bulkInsert() throws IOException {
        BulkRequest bulkRequest = new BulkRequest();
        bulkRequest.timeout("5s");

        List<Student> students = createList();
        for (Student student : students){
            bulkRequest.add(
                    new IndexRequest(INDEX_SCHOOL)
                            .id(student.getNo()+"")
                            .source(JSON.toJSONString(student), XContentType.JSON));
        }
        BulkResponse bulkResponse = client.bulk(bulkRequest,RequestOptions.DEFAULT);
        System.out.println(bulkResponse.status());
        System.out.println(bulkResponse.hasFailures()); // 是否失败，返回false 代表成功
        System.out.println(bulkResponse.getIngestTookInMillis());
        System.out.println(bulkResponse.getItems());
        System.out.println(bulkResponse.getTook());
        System.out.println(bulkResponse.toString());
    }

    public List<Student> createList(){
        List<Student> list = new ArrayList<>();
        Student zhangsan = new Student(103,"张三",26,"game 爱打Lol");
        Student lisi = new Student(104,"李四",26,"睡觉");
        Student wangwu = new Student(105,"王五",27,"打球");
        Student liuliu = new Student(106,"六六",28,"game 爱打绝地求生");
        list.add(zhangsan);
        list.add(lisi);
        list.add(wangwu);
        list.add(liuliu);
        return list;
    }

    /*
    * 查询
    *  SearchRequest 搜索请求
    *   SearchSourceBuilder  构造条件
    *       TermQueryBuilder  精确查询
    *       HighlightBuilder  构造高亮
    *       MatchAllQueryBuilder  匹配全部
    *       ****QueryBuilder
    * */
    @RequestMapping(value="search",method= RequestMethod.GET)
    @ResponseBody
    public  List<Map> search() throws IOException {

        SearchRequest searchRequest = new SearchRequest(INDEX_SCHOOL);
        // 构建条件
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        // 精确查询
        TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("like","game");

        searchSourceBuilder.query(termQueryBuilder);
        searchSourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));

        // 高亮
        HighlightBuilder highlightBuilder = new HighlightBuilder();
        highlightBuilder.field("like"); //高亮的字段
        highlightBuilder.requireFieldMatch(false); //关闭多个高亮
        highlightBuilder.preTags("<span style='color:red'>"); //高亮的字段
        highlightBuilder.postTags("</span>"); //高亮的字段
        searchSourceBuilder.highlighter(highlightBuilder);
        // 分页
       // searchSourceBuilder.from(1);
       // searchSourceBuilder.size(10);

        searchRequest.source(searchSourceBuilder);
        SearchResponse response = client.search(searchRequest,RequestOptions.DEFAULT);

        System.out.println(JSON.toJSONString(response.getHits()));
        System.out.println(response.status());
        System.out.println(JSON.toJSONString(response));
        List<Map> ret =new ArrayList<>();
        for(SearchHit searchHit : response.getHits().getHits()){

            //查询结果
            Map<String, Object> source = searchHit.getSourceAsMap();
            System.out.println(source);
            //获取高亮
            Map<String, HighlightField> highlightFields = searchHit.getHighlightFields();
            HighlightField highlightField = highlightFields.get("like");
            if(highlightField != null){
              //   进行 高亮替换searchHit 中的原来值
                Text[]  fragment = highlightField.fragments();
                String new_high = "";
                for(Text t : fragment){
                    new_high += t;
                }
                source.put("like",new_high);
            }
            ret.add(source);
        }
        return ret;
    }

}
